package com.nbicc.common.utils;

import com.google.common.base.Strings;
import com.nbicc.common.TreeNode;

import java.util.ArrayList;
import java.util.List;

/**
 * 把treenode实现类进行树状排序
 * @author li
 *
 * @param <T>
 */
public class TreeBuilder<T> {
	
	/**
	 * 把集合进行树状排序
	 * @param dirs		需要排序的集合
	 * @param pid		手工指定的根节点(可不填)
	 * @return
	 */
	public static List<TreeNode> buildListToTree(List<? extends TreeNode> dirs, String pid) {
        List<TreeNode> roots = findRoots(dirs, pid);
        for (TreeNode root : roots) {
            root.setChildren(findChildren(root, dirs));
        }
        return roots;
    }
	
	/**
	 * 获取根节点集合
	 * @param allTreeNodes
	 * @param pid
	 * @return
	 */
    public static List<TreeNode> findRoots(List<? extends TreeNode> allTreeNodes, String pid) {
        List<TreeNode> results = new ArrayList<TreeNode>();
        for (TreeNode treeNode : allTreeNodes) {
        	//父节点
        	if(treeNode != null){
        		if(!Strings.isNullOrEmpty(treeNode.id())){		//id绝对不能是空
            		if ((Strings.isNullOrEmpty(treeNode.pid()))	//如果pid为空 则为根节点
        					|| ("0".equals(treeNode.pid()) && !Strings.isNullOrEmpty(treeNode.id()))		//如果pid为0 则为根节点
        					|| treeNode.pid().equalsIgnoreCase(pid)) {										//如果pid为手工设置
        				results.add(treeNode);
        			}
            	}
        	}
        }
        return results;
    }

    /**
     * 查询出根节点下所有子节点
     * @param root
     * @param allTreeNodes
     * @return
     */
    private static List<TreeNode> findChildren(TreeNode root, List<? extends TreeNode> allTreeNodes) {
        List<TreeNode> children = new ArrayList<TreeNode>();

        //查询出根节点下一级的子节点
        for (TreeNode comparedOne : allTreeNodes) {
        	if(comparedOne!=null){
        		if (comparedOne.pid() != null && comparedOne.pid().equals(root.id())) {
        			children.add(comparedOne);
        		}
        	}
        }
        
        //如果有子节点  则递归获取下级子节点
        for (TreeNode child : children) {
			if (!Strings.isNullOrEmpty(child.id())) {
				List<TreeNode> tmpChildren = findChildren(child, allTreeNodes);
				child.setChildren(tmpChildren);
			}
            
        }
        return children;
    }
}
